#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/kallsyms.h>


struct ftrace_ops ft_ops;
const char *symbol_name = "_do_fork";
//const char *symbol_name = "sys_open";
unsigned long symbol_address;

void *orig_func = NULL;




static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip,
								struct ftrace_ops *ops, struct pt_regs *regs)
{

	pr_info("<%s>---%d current_task:%s, current_task.pid:%d\n", __func__, __LINE__, current->comm, current->pid);

	/* skip the functoin calls from the current module */
	if (!within_module(parent_ip, THIS_MODULE)) {
		pr_info("<%s>---%d current_task:%s, current_task.pid:%d\n", __func__, __LINE__, current->comm, current->pid);

		//orig_func;
	}
}




static int ftrace_hook_init(void)
{
	int err;

	symbol_address = kallsyms_lookup_name(symbol_name);
	if (!symbol_address) {
		pr_info("unresovle symbol: %s\n", symbol_name);
		return -ENOENT;
	}

	orig_func = (void *)symbol_address;


	ft_ops.func = fh_ftrace_thunk;
	ft_ops.flags = FTRACE_OPS_FL_SAVE_REGS
									| FTRACE_OPS_FL_IPMODIFY;

	err = ftrace_set_filter_ip(&ft_ops, symbol_address, 0, 0);
	if (err) {
		pr_info("ftrace_set_filter_ip() failed\n");
		return err;
	}


	err = register_ftrace_function(&ft_ops);
	if (err) {
		pr_info("register_ftrace_function() failed\n");
		ftrace_set_filter_ip(&ft_ops, symbol_address, 1, 0);

		return err;
	}


	return 0;
}


static void ftrace_hook_exit(void)
{
	int err;

	err = unregister_ftrace_function(&ft_ops);
	if (err) {
		pr_info("unregister_ftrace_function() failed\n");

	}

	err = ftrace_set_filter_ip(&ft_ops, symbol_address, 1, 0);
	if (err) {
		pr_info("ftrace_set_filter_ip failed\n");
	}
	

	return ;
}


module_init(ftrace_hook_init);
module_exit(ftrace_hook_exit);


MODULE_LICENSE("GPL");

